package com.tengxing.e1.FactoryTest;



import static com.serenegiant.utils.ThreadPool.queueEvent;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Point;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureFailure;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.params.StreamConfigurationMap;

import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbManager;
import android.media.Image;
import android.media.ImageReader;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;

import android.util.Log;
import android.util.Size;

import android.view.OrientationEventListener;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.TextureView;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.activity.EdgeToEdge;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

import android.util.DisplayMetrics;

import com.serenegiant.common.BaseActivity;
import com.serenegiant.usb.CameraDialog;
import com.serenegiant.usb.USBMonitor;
import com.serenegiant.usb.USBMonitor.OnDeviceConnectListener;
import com.serenegiant.usb.USBMonitor.UsbControlBlock;
import com.serenegiant.usb.UVCCamera;
import com.serenegiant.utils.HandlerThreadHandler;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

public class Camera_Test_Activity extends AppCompatActivity {
    private static final String TAG = "Camera_Test_Activity";
    SharedPreferences sharedPreferences;
    SharedPreferences.Editor editor;

    Button btn_Cam1, btn_Cam_Pass, btn_Cam_Fail;
    TextView tv_Cam;

    private Handler mChildHandler;
    private CameraManager mCameraManager;
    private String mCurrentCameraId;
    private Size mCurrentSelectSize;
    private ImageReader mImageReader;
    private TextureView mTextureView;
    private ImageView imageView;
    private CameraDevice.StateCallback mCameraDeviceStateCallback;
    private CameraDevice mCameraDevice;
    private Surface mSurface;
    private CaptureRequest.Builder mCaptureRequest;
    private CameraCaptureSession.StateCallback mCameraCaptureSessionStateCallback;
    private CameraCaptureSession.CaptureCallback mCameraCaptureSessionCaptureCallback;
    private CameraCaptureSession mCameraCaptureSession;
    private Integer cam_facing = CameraCharacteristics.LENS_FACING_BACK;

    //USB Camera start
    private static final boolean DEBUG = true;	// TODO set false when production
    private final Object mSync = new Object();
    // for accessing USB and USB camera
    private USBMonitor mUSBMonitor;
    private UVCCamera mUVCCamera;
    private SurfaceView mUVCCameraView;
    // for open&start / stop&close camera preview
    //private ImageButton mCameraButton;
    private Surface mPreviewSurface;
    private boolean isActive, isPreview;
    private Handler mWorkerHandler;
    private long mWorkerThreadID = -1;

    //USB Camera end
    //USB Camera O start
    private final Handler mAsyncHandler  = HandlerThreadHandler.createHandler(TAG);;
    private final ConcurrentHashMap<UsbDevice, UsbControlBlock> mCtrlBlocks = new ConcurrentHashMap<UsbDevice, UsbControlBlock>();
    private UsbManager usbManager;
    static{
        System.loadLibrary("jpeg-turbo1500");
    }
    //USB Camera O end
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_camera_test);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });
        sharedPreferences = getSharedPreferences("Test_Result", MODE_PRIVATE);

        if (mWorkerHandler == null) {
            mWorkerHandler = HandlerThreadHandler.createHandler(TAG);
            mWorkerThreadID = mWorkerHandler.getLooper().getThread().getId();
        }

        InitView();
        USB_Camera_Org_Init();
        Factory_Camera_Test_Init();

    }

    //USB Camera O start
    void USB_Camera_Org_Init(){
        usbManager = (UsbManager) getSystemService(USB_SERVICE);
        USB_Camera_InitView();//serenegiant usb camera*/
        tryGetUsbPermission();

        Get_USB_Camera();
    }
    private void Get_USB_Camera(){
        String usb_dev_str="";
        for(UsbDevice usbDevice : usbManager.getDeviceList().values()){
            usb_dev_str = usb_dev_str.concat("dev:" + usbDevice.getDeviceName() +
                    " class:" + usbDevice.getDeviceClass() +
                    " id:"+ usbDevice.getDeviceId() +
                    " pd_Name:"+ usbDevice.getProductName()+
                    "\n");
        }
        /*for(UsbDevice usbDevice : usbManager.getDeviceList().values()){
            if(usbDevice.getProductName() == null){
                usb_dev_str = usb_dev_str.concat("dev=" + usbDevice.getDeviceName() + " ProductName:null\n");
                continue;
            }
            if(usbDevice.getProductName().contains("Camera") || usbDevice.getProductName().contains("camera")){
                usb_dev_str = usb_dev_str.concat("dev=" + usbDevice.getDeviceName() + " ProductName:" + usbDevice.getProductName() + "\n");
            }
        }*/
        tv_Cam.setText(usb_dev_str);

        //StartP();
    }
    void StartP() {
        final float[] BANDWIDTH_FACTORS = {1.0f, 1.0f};
        mUVCCamera = new UVCCamera();
        //mUVCCamera.open();
        //USBMonitor.UsbControlBlock
        //mUVCCamera.startPreview();
        if (mUVCCamera == null) {
            return;
        }
        Log.d(TAG," startPreview");
        int width = UVCCamera.DEFAULT_PREVIEW_WIDTH, height = UVCCamera.DEFAULT_PREVIEW_HEIGHT;
        if (true) {
            width = 1280;
            height = 720;
            int s1 = width * height;
            com.serenegiant.usb.Size size = null;
            List<com.serenegiant.usb.Size> sizes = mUVCCamera.getSupportedSizeList();
            StringBuilder size_log = new StringBuilder( "支持的分辨率为：\n");
            for (com.serenegiant.usb.Size s : sizes) {
                if (s.height == height || s.width == width) {
                    if (size == null || Math.abs((s.width * s.height) - s1) < Math.abs((size.width * size.height) - s1)) {
                        size = s;
                    }
                }
                size_log.append(s.toString()).append(";\n");
            }
            Log.d(TAG, size_log.toString());
            if (size != null) {
                width = size.width;
                height = size.height;
            }
        }

        try {
            mUVCCamera.setPreviewSize(width, height, 1, 30, UVCCamera.FRAME_FORMAT_MJPEG, BANDWIDTH_FACTORS[0]);
            Log.d(TAG, "设置分辨率为：" + width + "*" + height);
        } catch (IllegalArgumentException e) {
            Log.w(TAG, "setPreviewSize error:" + e.getMessage());
        }
        /*final SurfaceTexture st = mTextureView.getSurfaceTexture();
        mUVCCamera.setPreviewTexture(st);

        mUVCCamera.startPreview();
        mUVCCamera.updateCameraParams();*/

        mPreviewSurface = mUVCCameraView.getHolder().getSurface();
        if (mPreviewSurface != null) {
            mUVCCamera.setPreviewDisplay(mPreviewSurface);
            mUVCCamera.startPreview();
        }
//        this.handler.sendEmptyMessageDelayed(MSG_START_PREVIEW, 5 * 1000);
    }

    private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";

    private void tryGetUsbPermission(){
        //usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);

        IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
        registerReceiver(mUsbPermissionActionReceiver, filter);

        PendingIntent mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);

        //here do emulation to ask all connected usb device for permission
        for (final UsbDevice usbDevice : usbManager.getDeviceList().values()) {
            //add some conditional check if necessary
            //if(isWeCaredUsbDevice(usbDevice)){
            if(usbManager.hasPermission(usbDevice)){
                //if has already got permission, just goto connect it
                //that means: user has choose yes for your previously popup window asking for grant perssion for this usb device
                //and also choose option: not ask again
                afterGetUsbPermission(usbDevice);
            }else{
                //this line will let android popup window, ask user whether to allow this app to have permission to operate this usb device
                usbManager.requestPermission(usbDevice, mPermissionIntent);
            }
            //}
        }
    }
    private void afterGetUsbPermission(UsbDevice usbDevice){
        //call method to set up device communication
        //Toast.makeText(Camera_Test_Activity.this, String.valueOf("Got permission for usb device: " + usbDevice), Toast.LENGTH_LONG).show();
        //Toast.makeText(Camera_Test_Activity.this, String.valueOf("Found USB device: VID=" + usbDevice.getVendorId() + " PID=" + usbDevice.getProductId()), Toast.LENGTH_LONG).show();

        doYourOpenUsbDevice(usbDevice);
    }

    private void doYourOpenUsbDevice(UsbDevice usbDevice){
        //now follow line will NOT show: User has not given permission to device UsbDevice
        //UsbDeviceConnection connection = usbManager.openDevice(usbDevice);
        //add your operation code here
        UsbDeviceConnection connection;

        if(usbDevice.getProductName()!=null){
            if (DEBUG) Log.d(TAG, "UsbPermission: " + usbDevice.getProductName());
            if(usbDevice.getProductName().contains("Camera") || usbDevice.getProductName().contains("camera")){
                //connection = usbManager.openDevice(usbDevice);
                //mUVCCamera.startPreview();
            }
        }



        //StartP();
    }

    private final BroadcastReceiver mUsbPermissionActionReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (ACTION_USB_PERMISSION.equals(action)) {
                synchronized (this) {
                    UsbDevice usbDevice = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                        //user choose YES for your previously popup window asking for grant perssion for this usb device
                        if(null != usbDevice){
                            afterGetUsbPermission(usbDevice);
                        }
                    }
                    else {
                        //user choose NO for your previously popup window asking for grant perssion for this usb device
                        Toast.makeText(context, String.valueOf("Permission denied for device" + usbDevice), Toast.LENGTH_LONG).show();
                    }
                }
            }
        }
    };


    //USB Camera O end


    //USB Camera start
    void USB_Camera_InitView(){
        mUVCCameraView = (SurfaceView)findViewById(R.id.surfaceView_Cam);
        mUVCCameraView.getHolder().addCallback(mSurfaceViewCallback);
        mUSBMonitor = new USBMonitor(this, mOnDeviceConnectListener);//serenegiant usb camera*/

        //CameraDialog.showDialog(Camera_Test_Activity.this);
    }
    

    @Override
    protected void onStart() {
        super.onStart();
        //Log.v(TAG, "onStart:");
        synchronized (mSync) {
            if (mUSBMonitor != null) {
                mUSBMonitor.register();

            }
            if (mUVCCamera != null){
                mUVCCamera.startPreview();
            }
        }
    }

    @Override
    protected void onStop() {
        //Log.v(TAG, "onStop:");
        synchronized (mSync) {
            if (mUSBMonitor != null) {
                mUSBMonitor.unregister();
            }
            if (mUVCCamera != null) {
                mUVCCamera.stopPreview();
            }
        }
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        //Log.v(TAG, "onDestroy:");
        synchronized (mSync) {
            isActive = isPreview = false;
            if (mUVCCamera != null) {
                mUVCCamera.destroy();
                mUVCCamera = null;
            }
            if (mUSBMonitor != null) {
                mUSBMonitor.destroy();
                mUSBMonitor = null;
            }
        }
        mUVCCameraView = null;
        super.onDestroy();
    }


    private final OnDeviceConnectListener mOnDeviceConnectListener = new OnDeviceConnectListener() {
        @Override
        public void onAttach(final UsbDevice device) {
            if (DEBUG) Log.v(TAG, "onAttach: dev="+ device.getDeviceId() + " pd_name:" + device.getProductName());
            Toast.makeText(Camera_Test_Activity.this, "USB_DEVICE_ATTACHED\ndev="+ device.getDeviceId() + " pd_name:" + device.getProductName(), Toast.LENGTH_SHORT).show();
            mUSBMonitor.requestPermission(device);
        }

        @Override
        public void onConnect(final UsbDevice device, final UsbControlBlock ctrlBlock, final boolean createNew) {

            if (DEBUG) Log.v(TAG, "onConnect:" + device.getProductName());
            if(device.getProductName() == null){
                if (DEBUG) Log.d(TAG, "onConnect: no usb dev");
                return;
            }
            if(device.getProductName().contains("Camera") || device.getProductName().contains("camera")){
                if (DEBUG) Log.d(TAG, "onConnect: usb cam dev find.");
            }else{
                if (DEBUG) Log.d(TAG, "onConnect: no usb cam dev.");
                return;
            }
            synchronized (mSync) {
                if (DEBUG) Log.d(TAG, "mUVCCamera: mSync");
                if (mUVCCamera != null) {
                    if (DEBUG) Log.d(TAG, "mUVCCamera: not null");
                    mUVCCamera.destroy();
                }
                isActive = isPreview = false;
            }
            queueEvent(new Runnable() {
                @Override
                public void run() {
                    if (DEBUG) Log.d(TAG, "queueEvent:" + device.getProductName());
                    synchronized (mSync) {
                        final UVCCamera camera = new UVCCamera();
                        camera.open(ctrlBlock);
                        if (DEBUG) Log.d(TAG, "supportedSize:" + camera.getSupportedSize());
                        try {
                            camera.setPreviewSize(UVCCamera.DEFAULT_PREVIEW_WIDTH, UVCCamera.DEFAULT_PREVIEW_HEIGHT, UVCCamera.FRAME_FORMAT_MJPEG);
                        } catch (final IllegalArgumentException e) {
                            try {
                                // fallback to YUV mode
                                camera.setPreviewSize(UVCCamera.DEFAULT_PREVIEW_WIDTH, UVCCamera.DEFAULT_PREVIEW_HEIGHT, UVCCamera.DEFAULT_PREVIEW_MODE);
                            } catch (final IllegalArgumentException e1) {
                                camera.destroy();
                                return;
                            }
                        }
                        mPreviewSurface = mUVCCameraView.getHolder().getSurface();
                        if (mPreviewSurface != null) {
                            isActive = true;
                            camera.setPreviewDisplay(mPreviewSurface);
                            camera.startPreview();
                            isPreview = true;
                        }
                        synchronized (mSync) {
                            mUVCCamera = camera;
                        }
                    }
                }
            });
        }

        @Override
        public void onDisconnect(final UsbDevice device, final UsbControlBlock ctrlBlock) {
            if (DEBUG) Log.v(TAG, "onDisconnect:");
            // XXX you should check whether the comming device equal to camera device that currently using
            queueEvent(new Runnable() {
                @Override
                public void run() {
                    synchronized (mSync) {
                        if (mUVCCamera != null) {
                            mUVCCamera.close();
                            if (mPreviewSurface != null) {
                                mPreviewSurface.release();
                                mPreviewSurface = null;
                            }
                            isActive = isPreview = false;
                        }
                    }
                }
            });
        }

        @Override
        public void onDettach(final UsbDevice device) {
            if (DEBUG) Log.v(TAG, "onDettach:");
            Toast.makeText(Camera_Test_Activity.this, "USB_DEVICE_DETACHED", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onCancel(final UsbDevice device) {
        }
    };

    /**
     * to access from CameraDialog
     * @return
     */
    /*@Override
    public USBMonitor getUSBMonitor() {
        return mUSBMonitor;
    }

    @Override
    public void onDialogResult(boolean canceled) {
        if (canceled) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // FIXME
                }
            }, 0);
        }
    }*/

    private final SurfaceHolder.Callback mSurfaceViewCallback = new SurfaceHolder.Callback() {
        @Override
        public void surfaceCreated(final SurfaceHolder holder) {
            if (DEBUG) Log.v(TAG, "surfaceCreated:");
        }

        @Override
        public void surfaceChanged(final SurfaceHolder holder, final int format, final int width, final int height) {
            if ((width == 0) || (height == 0)) return;
            if (DEBUG) Log.v(TAG, "surfaceChanged:");
            mPreviewSurface = holder.getSurface();
            synchronized (mSync) {
                if (isActive && !isPreview && (mUVCCamera != null)) {
                    mUVCCamera.setPreviewDisplay(mPreviewSurface);
                    mUVCCamera.startPreview();
                    isPreview = true;
                }
            }
        }

        @Override
        public void surfaceDestroyed(final SurfaceHolder holder) {
            if (DEBUG) Log.v(TAG, "surfaceDestroyed:");
            synchronized (mSync) {
                if (mUVCCamera != null) {
                    mUVCCamera.stopPreview();
                }
                isPreview = false;
            }
            mPreviewSurface = null;
        }
    };

    /*protected final synchronized void queueEvent(final Runnable task, final long delayMillis) {
        if ((task == null) || (mWorkerHandler == null)) return;
        try {
            mWorkerHandler.removeCallbacks(task);
            if (delayMillis > 0) {
                mWorkerHandler.postDelayed(task, delayMillis);
            } else if (mWorkerThreadID == Thread.currentThread().getId()) {
                task.run();
            } else {
                mWorkerHandler.post(task);
            }
        } catch (final Exception e) {
            Log.e(TAG, "queueEvent:"+e);
        }
    }//*/
    //USB Camera end

    void InitView(){
        Factory_Camera_Test_BTN();
        tv_Cam = findViewById(R.id.tv_Cam);


    }

    void Factory_Camera_Test_BTN() {
        btn_Cam_Pass = findViewById(R.id.btn_Cam_Pass);
        btn_Cam_Pass.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                editor = sharedPreferences.edit();
                editor = editor.putString("Cam", "通过");
                if (editor.commit()) {
                    Toast.makeText(Camera_Test_Activity.this, "测试结果保存成功", Toast.LENGTH_SHORT).show();
                    Intent intent = new Intent(Camera_Test_Activity.this, MainActivity.class);
                    startActivity(intent);
                    finish();
                } else {
                    Toast.makeText(Camera_Test_Activity.this, "测试结果保存失败", Toast.LENGTH_SHORT).show();
                }
            }
        });

        btn_Cam_Fail = findViewById(R.id.btn_Cam_Fail);
        btn_Cam_Fail.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                editor = sharedPreferences.edit();
                editor = editor.putString("Cam", "未通过");
                if (editor.commit()) {
                    Toast.makeText(Camera_Test_Activity.this, "测试结果保存成功", Toast.LENGTH_SHORT).show();
                    Intent intent = new Intent(Camera_Test_Activity.this, MainActivity.class);
                    startActivity(intent);
                    finish();
                } else {
                    Toast.makeText(Camera_Test_Activity.this, "测试结果保存失败", Toast.LENGTH_SHORT).show();
                }
            }
        });

        btn_Cam1 = findViewById(R.id.btn_Cam1);
        btn_Cam1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Switch_Camera();
                //takePicture();
            }
        });
    }

    void Factory_Camera_Test_Init() {
        imageView = findViewById(R.id.imageView_Cam);
        mTextureView = findViewById(R.id.textureView_Cam);
        initChildThread();
        initCameraManager();
        initSelectCamera();
        initHandlerMatchingSize();
        initImageReader();
        initTextureViewListener();
        initCameraDeviceStateCallbackListener();
        initCameraCaptureSessionStateCallbackListener();
        initCameraCaptureSessionCaptureCallbackListener();
    }

    private void initChildThread() {
        HandlerThread handlerThread = new HandlerThread("faceCamera");
        handlerThread.start();
        mChildHandler = new Handler(handlerThread.getLooper());

    }

    /**
     * 初始化相机管理
     */
    private void initCameraManager() {
        mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
    }


    /**
     * 初始化选择摄像头
     */
    private void initSelectCamera() {
        try {
            String[] cameraIdArray = mCameraManager.getCameraIdList();
            /*for(String itemId : cameraIdArray){
                Log.d(TAG, "cameraIdArray:" + itemId);
            }*/
            for (String itemId : cameraIdArray) {
                CameraCharacteristics itemCharacteristics = mCameraManager.getCameraCharacteristics(itemId);
                Integer facing = itemCharacteristics.get(CameraCharacteristics.LENS_FACING);
                if (facing == cam_facing) {
                    mCurrentCameraId = itemId;
                    break;
                }
            }
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
        if (mCurrentCameraId == null) {
            finish();
            Toast.makeText(this, "找不到摄像头", Toast.LENGTH_SHORT).show();
        }

    }

    /**
     * 初始化计算适合当前屏幕分辨率的拍照分辨率
     * @return
     */
    private void initHandlerMatchingSize() {
        try {
            CameraCharacteristics cameraCharacteristics = mCameraManager.getCameraCharacteristics(mCurrentCameraId);
            StreamConfigurationMap streamConfigurationMap = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
            Size[] sizes = streamConfigurationMap.getOutputSizes(ImageFormat.JPEG);
            DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
            int deviceWidth = displayMetrics.widthPixels;
            int deviceHeigh = displayMetrics.heightPixels;
            Log.e(TAG,"当前屏幕密度宽度="+deviceWidth+"高度="+deviceHeigh);
            for (int j = 1; j < 81; j++) {
                for (int i = 0; i < sizes.length; i++) {
                    Size itemSize = sizes[i];
                    if (itemSize.getHeight() < (deviceWidth + j * 5) && itemSize.getHeight() > (deviceWidth - j * 5)) {
                        if (mCurrentSelectSize != null) { //如果之前已经找到一个匹配的宽度
                            if (Math.abs(deviceHeigh-itemSize.getWidth()) < Math.abs(deviceHeigh - mCurrentSelectSize.getWidth())){ //求绝对值算出最接近设备高度的尺寸
                                mCurrentSelectSize = itemSize;
                                continue;

                            }
                        }else {
                            mCurrentSelectSize = itemSize;
                        }

                    }
                }

            }
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
        Log.e(TAG,"当前预览宽度="+mCurrentSelectSize.getWidth()+"高度="+mCurrentSelectSize.getHeight());
    }

    private void initImageReader() {
        Log.e(TAG,"初始化图片ImageReader的宽="+mCurrentSelectSize.getWidth()+"高="+mCurrentSelectSize.getHeight());
        mImageReader = ImageReader.newInstance(mCurrentSelectSize.getWidth()
                , mCurrentSelectSize.getHeight()
                , ImageFormat.JPEG
                , 1);

        mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
            @Override
            public void onImageAvailable(ImageReader reader) {

                Image image = reader.acquireLatestImage();
                ByteBuffer byteBuffer = image.getPlanes()[0].getBuffer();
                byte[] bytes = new byte[byteBuffer.remaining()];
                byteBuffer.get(bytes);
                /*final Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
                if (bitmap != null) {
                    //imageView.setImageBitmap(bitmap);
                }*/

                String path= Environment.getExternalStorageDirectory()+"/DCIM/FactoryTest_Camera/";
                File mImageFile=new File(path);
                if(!mImageFile.exists()){
                    mImageFile.mkdir();     //如果路径不存在就建一个
                }
                //文件命名方式：年月日_时分秒
                String timeStamp=new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
                String fileName=path+"IMG_FactoryTest_"+timeStamp+".jpg";
                try {
                    FileOutputStream fos=new FileOutputStream(fileName);
                    fos.write(bytes,0,bytes.length);    //写出图片
                } catch (FileNotFoundException e) {
                    throw new RuntimeException(e);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }


                // 处理完后记得释放资源
                //image.close();

            }
        }, mChildHandler);
    }

    private void initTextureViewListener() {
        mTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
            @Override
            public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
                openCamera();

            }

            @Override
            public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {

            }

            @Override
            public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
                return true;
            }

            @Override
            public void onSurfaceTextureUpdated(SurfaceTexture surface) {

            }
        });
    }

    private void initCameraDeviceStateCallbackListener() {
        mCameraDeviceStateCallback = new CameraDevice.StateCallback() {
            @Override
            public void onOpened(@NonNull CameraDevice camera) {
                //相机开启
                mCameraDevice = camera;
                try {
                    SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
                    surfaceTexture.setDefaultBufferSize(mCurrentSelectSize.getWidth(),mCurrentSelectSize.getHeight());
                    mSurface = new Surface(surfaceTexture);
                    mCaptureRequest = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
                    mCaptureRequest.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
                    mCaptureRequest.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);//自动爆光
                    mCaptureRequest.addTarget(mSurface);
                    mCameraDevice.createCaptureSession(Arrays.asList(mSurface, mImageReader.getSurface())
                            , mCameraCaptureSessionStateCallback
                            , mChildHandler);

                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }

            }

            @Override
            public void onDisconnected(@NonNull CameraDevice camera) {

            }

            @Override
            public void onError(@NonNull CameraDevice camera, int error) {
                finish();
                Toast.makeText(Camera_Test_Activity.this, "相机打开失败", Toast.LENGTH_SHORT).show();
                Log.e(TAG,"CameraDevice.StateCallback onError : 相机异常 error code="+error);

            }
        };
    }

    private void initCameraCaptureSessionStateCallbackListener() {
        mCameraCaptureSessionStateCallback = new CameraCaptureSession.StateCallback() {
            @Override
            public void onConfigured(@NonNull CameraCaptureSession session) {
                mCameraCaptureSession = session;
                startPreview();

            }

            @Override
            public void onConfigureFailed(@NonNull CameraCaptureSession session) {
                finish();
                Toast.makeText(Camera_Test_Activity.this, "相机打开失败", Toast.LENGTH_SHORT).show();
                Log.e(TAG,"CameraCaptureSession.StateCallback onConfigureFailed : CameraCaptureSession会话通道创建失败");

            }
        };
    }

    private void initCameraCaptureSessionCaptureCallbackListener() {
        mCameraCaptureSessionCaptureCallback = new CameraCaptureSession.CaptureCallback() {
            @Override
            public void onCaptureStarted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, long timestamp, long frameNumber) {
                super.onCaptureStarted(session, request, timestamp, frameNumber);
                //获取开始
            }

            @Override
            public void onCaptureProgressed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureResult partialResult) {
                super.onCaptureProgressed(session, request, partialResult);
                //获取中
            }

            @Override
            public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
                super.onCaptureCompleted(session, request, result);
                //获取结束
            }

            @Override
            public void onCaptureFailed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureFailure failure) {
                super.onCaptureFailed(session, request, failure);
                //获取失败

                Toast.makeText(Camera_Test_Activity.this, "拍照失败", Toast.LENGTH_SHORT).show();
                Log.e(TAG,"失败报告Reason="+failure.getReason());

            }
        };
    }
    /**
     * 打开摄像头
     */
    @SuppressLint("MissingPermission")
    private void openCamera() {
        try {
            mCameraManager.openCamera(mCurrentCameraId, mCameraDeviceStateCallback, mChildHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }



    /**
     * 开始预览
     */
    private void startPreview(){
        try {
            mCameraCaptureSession.setRepeatingRequest(mCaptureRequest.build(), mCameraCaptureSessionCaptureCallback, mChildHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    /**
     * 停止预览
     */
    private void stopPreview(){
        try {
            mCameraCaptureSession.stopRepeating();
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }

    }

    /**
     * 拍照
     */
    private void takePicture(){
        try {
            CaptureRequest.Builder takePictureRequest = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
            takePictureRequest.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);//自动对焦
            takePictureRequest.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);//自动爆光
            int rotation = getWindowManager().getDefaultDisplay().getRotation();
            int angle = getJpegOrientation(mCameraManager.getCameraCharacteristics(mCurrentCameraId), rotation);
            Log.i(TAG,"照片角度="+angle);
            takePictureRequest.set(CaptureRequest.JPEG_ORIENTATION, angle);
            Surface surface = mImageReader.getSurface();
            takePictureRequest.addTarget(surface);
            CaptureRequest request = takePictureRequest.build();
            mCameraCaptureSession.capture(request, null, mChildHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }

    }

    /**
     * 官方提供的JPEG图片方向算法
     * @param c
     * @param deviceOrientation
     * @return
     */
    private int getJpegOrientation(CameraCharacteristics c, int deviceOrientation) {
        if (deviceOrientation == OrientationEventListener.ORIENTATION_UNKNOWN){
            return 0;
        }
        int sensorOrientation = c.get(CameraCharacteristics.SENSOR_ORIENTATION);//获取传感器方向

        // Round device orientation to a multiple of 90
        deviceOrientation = (deviceOrientation + 45) / 90 * 90;

        // Reverse device orientation for front-facing cameras
        boolean facingFront = c.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT;//判断摄像头面向
        if (facingFront) {
            deviceOrientation = -deviceOrientation;
        }

        // Calculate desired JPEG orientation relative to camera orientation to make
        // the image upright relative to the device orientation
        int jpegOrientation = (sensorOrientation + deviceOrientation + 360) % 360;

        return jpegOrientation;
    }



    private void Switch_Camera(){
        mCameraManager = null;
        if(cam_facing == CameraCharacteristics.LENS_FACING_BACK){
            cam_facing = CameraCharacteristics.LENS_FACING_FRONT;
        }else{
            cam_facing = CameraCharacteristics.LENS_FACING_BACK;
        }
        initCameraManager();
        initSelectCamera();
        try{
            mCameraManager.openCamera(mCurrentCameraId, mCameraDeviceStateCallback, mChildHandler);
        }catch (Exception e){

        }

    }

    private void Close_Camera(){
        if (mImageReader != null){
            mImageReader.close();
            mImageReader = null;
        }
        if (mCameraCaptureSession != null){
            stopPreview();
            try {
                mCameraCaptureSession.abortCaptures();
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }
            mCameraCaptureSession.close();
            mCameraCaptureSession = null;
        }
        if (mCaptureRequest != null){
            mCaptureRequest.removeTarget(mSurface);//注意释放mSurface
            mCaptureRequest = null;
        }
        if (mSurface != null){
            mSurface.release();//注意释放mSurface
            mSurface = null;
        }
        //也可以用onSurfaceTextureDestroyed这种方式释放SurfaceTexture 但是在上面的public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) 回调中你需要返回true或者自己执行 surface.release(); 这步资源释放很重要
        mTextureView.getSurfaceTextureListener().onSurfaceTextureDestroyed(mTextureView.getSurfaceTexture());
        mCameraDeviceStateCallback = null;
        mCameraCaptureSessionStateCallback = null;
        mCameraCaptureSessionCaptureCallback = null;
        mCameraManager = null;
        if (mCameraDevice != null){
            mCameraDevice.close();
            mCameraDevice = null;
        }
        mCameraManager = null;
        if (mChildHandler != null){
            mChildHandler.removeCallbacksAndMessages(null);
            mChildHandler = null;

        }
    }


    @Override
    public void onBackPressed() {
        Close_Camera();
        Intent intent = new Intent(Camera_Test_Activity.this, MainActivity.class);
        startActivity(intent);
        finish();
        Toast.makeText(Camera_Test_Activity.this, "直接退出不会保存结果", Toast.LENGTH_SHORT).show();
        super.onBackPressed();
    }
}